/////////////////////////////////////////////////////////////////////////
//
// Amuse Engine SDK - core/containment
// Copyright( c) 2013.  All Rights Reserved
//
// File:		AETFixedSizeStack.h
// Author:		Gianluca Belardelli
// Date:		05/10/2013
//
/////////////////////////////////////////////////////////////////////////
#ifndef _AETFIXEDSIZESTACK_H_
#define _AETFIXEDSIZESTACK_H_

/// \brief
/// Classe base per l'implementazione di stack a grandezza fissa.
/// La classe non gestisce l'allocazione dinamica della memoria,
/// utilizzare invece AETFixedSizeStack.
template<typename T>
class AETFixedSizeStackBase
{
	AE_DECLARE_NON_COPYABLE( AETFixedSizeStackBase );

// Members
protected:
	T			*m_lpData;
	AEUINT32	m_uiDataSize;
	AEUINT32	m_uiSize;

// Methods
private:
protected:
	///////////////////////////////////////////////////////////////
	/// @name Costruttore
	/// @{
	///////////////////////////////////////////////////////////////

	AE_FORCEINLINE AETFixedSizeStackBase( T *lpData, AEUINT32 uiSize );

public:
	///////////////////////////////////////////////////////////////
	/// @}
	/// @name Accesso ai dati
	/// @{
	///////////////////////////////////////////////////////////////

	/// \brief
	/// Salva un nuovo oggetto sullo stack.
	/// \param value
	/// L'oggetto da salvare
	AE_FORCEINLINE void Push( const T &tValue );

	/// \brief
	/// Recupera un oggetto dallo stack.
	/// \return
	/// L'oggetto in cima allo stack.
	AE_FORCEINLINE T Pop( void );

	/// \brief
	/// Recupera l'oggetto in cima allo stack senza toglierlo.
	/// \return
	/// L'oggetto in cima allo stack.
	AE_FORCEINLINE T &Top( void );

	/// \brief
	/// Recupera l'oggetto in cima allo stack senza toglierlo.
	/// \return
	/// L'oggetto in cima allo stack.
	AE_FORCEINLINE const T &Top( void ) const;

	/// \brief
	/// Ritorna il numero di elementi presenti nello stack.
	AE_FORCEINLINE AEUINT32 GetSize( void ) const;

	/// \brief
	/// Operatore [] per l'accesso random agli elementi dello stack.
	/// \param index
	/// L'indice dell'elemento da ritornare.
	/// \return
	/// L'oggetto all'indice selezionato senza toglierlo dallo stack.
	AE_FORCEINLINE T &operator []( AEUINT32 uiIndex );

	/// \brief
	/// Operatore [] per l'accesso random agli elementi dello stack.
	/// \param index
	/// L'indice dell'elemento da ritornare.
	/// \return
	/// L'oggetto all'indice selezionato senza toglierlo dallo stack.
	AE_FORCEINLINE const T &operator []( AEUINT32 uiIndex ) const;
};

/// \brief
/// La classe implementa uno stack a grandezza fissa utilizzando memoria statica.
template<typename T,AEUINT32 size>
class AETFixedSizeStack : public AETFixedSizeStackBase<T>
{
// Members
private:
	T m_arrData[ size ] ;

// Methods
public:
	/// \brief
	///   Constructor
	AE_FORCEINLINE AETFixedSizeStack( void );
};

#include "AETFixedSizeStack.inl"

#endif // _AETFIXEDSIZESTACK_H_
